/* For this demo, make sure the `#define S302_SERIAL` macro is chosen in the library. */ #include // These values are in microseconds #define STEP_TIME 10000 #define REPORT_TIME 100000 #define SQ_WAVE_PEAK 228 #define SQ_PERIOD 30000 // Period of driving square wave cycle in ms. #define SQ_WAVE_ZERO 128 #define DAC1PIN 25 #define DAC2PIN 26 #define ADCPIN 36 #define LED 2 CommManager cm(STEP_TIME, REPORT_TIME); float adcValue, floatU; int32_t initMillis, myMilliseconds, sqAmp = SQ_WAVE_PEAK, u = 128; bool state = true; // Start with no state feedback float R = 22000.0; float C = 470e-6; void setup() { pinMode(LED, OUTPUT); dacWrite(DAC2PIN, 128); // Setup our "GND" /* Add modules */ cm.addPlot(&adcValue, "ADC Voltage", -0.1, 3.3 / 2., 2000, 1); cm.addNumber(&myMilliseconds, "Milliseconds"); cm.addNumber(&u, "u"); cm.addToggle(&state, "Apply State Feedback"); cm.addPlot(&floatU, "u", 0, 256, 2000, 1); initMillis = millis(); /* Ready to communicate over serial */ cm.connect(&Serial, 115200); } void loop() { if (millis() - initMillis > SQ_PERIOD) { initMillis = millis(); if (sqAmp == SQ_WAVE_PEAK) { sqAmp = SQ_WAVE_ZERO; } else { sqAmp = SQ_WAVE_PEAK; } } adcValue = (analogRead(ADCPIN) - 4096 / 2) * 3.3 / 4096; // Read the difference between "GND" and v_c. // This should place the pole as -2/(R*C). if (u >= 255) { u = 255; digitalWrite(LED, HIGH); } else if (u <= 0) { u = 0; digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } if (!state | (sqAmp == SQ_WAVE_PEAK)) { u = sqAmp; } else { u = sqAmp - (int)(adcValue * 9 / R / C * 256.0 / 3.3); // G = 1,u = - B*G*v_c. The conversion from DAC1 value to volts is (256/3.3V). } floatU = float(u); dacWrite(DAC1PIN, u); myMilliseconds = (int32_t)millis(); cm.step(); };